package repo

import (
	"fmt"
	"strings"
)

type Table struct {
	Schema  string
	Name    string
	Comment string
	Cols    []Column
	Pks     []Column
}

// 注意： 下面的gorm 的字段的tag 是大写的！！！！
type Column struct {
	Name    string `gorm:"column:COLUMN_NAME"`              // 列名
	Type    string `gorm:"column:DATA_TYPE"`                // 类型
	Len     int    `gorm:"column:CHARACTER_MAXIMUM_LENGTH"` // 长度
	Key     string `gorm:"column:COLUMN_KEY"`               // 索引
	Comment string `gorm:"column:COLUMN_COMMENT"`           // 注释
}

func (c *Column) TableName() string {
	return "information_schema.columns"
}

// GetAllTables 获取数据库里的所有的表
func GetAllTables(dbname string) []*Table {
	sql := "select table_name, table_comment from information_schema.tables where table_schema = ? and table_type=?"
	rows, err := db.Raw(sql, dbname, "BASE TABLE").Rows()
	if err != nil {
		panic(fmt.Errorf("GetAllTables err: %v", err))
	}
	var tbls []*Table
	for rows.Next() {
		var tn, tc string
		rows.Scan(&tn, &tc)
		tbls = append(tbls, &Table{Name: tn, Comment: tc, Schema: dbname})
	}
	return tbls
}

// func GetTableCols2(dbname string, tbl *Table) {
// 	list := make([]*Column, 0)
// 	err := db.Raw("SHOW FULL COLUMNS FROM ?", tbl.Name).Select("Field as column_name, Comment column_comment").Scan(&list).Error
// 	if err != nil {
// 		panic(fmt.Errorf("GetAllTables err: %v", err))
// 	}
// 	for _, l := range list {
// 		fmt.Printf("cols: %#v\n", *l)
// 		tbl.Cols = append(tbl.Cols, *l)
// 	}
// }

func GetTableCols(dbname string, tbl *Table) {
	list := make([]*Column, 0)
	err := db.Model(&Column{}).Select("column_name, data_type, character_maximum_length,column_key,column_comment").Where("table_schema = ? and  table_name = ?", dbname, tbl.Name).Order("ordinal_position").Scan(&list).Error
	if err != nil {
		panic(fmt.Errorf("GetAllTables err: %v", err))
	}
	for _, l := range list {
		fmt.Printf("cols: %#v\n", *l)
		l.Comment = strings.ReplaceAll(l.Comment, "\n", ";")
		tbl.Cols = append(tbl.Cols, *l)
	}
}

// GetTable 得到表的信息
func GetTable(dbname string, tbl *Table) {
	sql := "select column_name, Data_type, character_maximum_length,column_key,column_comment from information_schema.columns where table_schema = ? and  table_name = ?"
	rows, err := db.Raw(sql, dbname, tbl.Name).Rows()
	if err != nil {
		panic(fmt.Errorf("GetAllTables err: %v", err))
	}
	defer rows.Close()
	for rows.Next() {
		var name, dataType, comment string
		var len int
		var skey interface{}
		rows.Scan(&name, &dataType, &len, &skey, &comment)
		var col = &Column{
			Name:    name,
			Type:    dataType,
			Len:     len,
			Key:     fmt.Sprintf("%v", skey),
			Comment: comment,
		}
		tbl.Cols = append(tbl.Cols, *col)
		if col.Key == "PRI" {
			tbl.Pks = append(tbl.Pks, *col)
		}
	}
}
